package com.cgnpc.scp.purchase.service.impl;

import cn.com.cgnpc.aep.bizcenter.appcenter.sdk.result.ApiResult;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cgnpc.cuddemo.funcInstance.service.ICudFileService;
import com.cgnpc.cuddemo.utils.IDHelper;
import com.cgnpc.framework.service.IBpmCenterService;
import com.cgnpc.framework.userinfo.CurrentUser;
import com.cgnpc.scp.common.exception.ScpException;
import com.cgnpc.scp.common.pojo.ActivityInfoParams;
import com.cgnpc.scp.common.pojo.UserInfo;
import com.cgnpc.scp.common.utils.BpmUtil;
import com.cgnpc.scp.common.utils.StringUtil;
import com.cgnpc.scp.purchase.mybatis.entity.*;
import com.cgnpc.scp.purchase.mybatis.mapper.client.ContractProcessItemMapper;
import com.cgnpc.scp.purchase.mybatis.mapper.client.NonContractProcessApplyMapper;
import com.cgnpc.scp.purchase.mybatis.mapper.client.NonContractProcessAuditMapper;
import com.cgnpc.scp.purchase.mybatis.mapper.client.PurchaseContractItemMapper;
import com.cgnpc.scp.purchase.service.ICommonProcessService;
import com.cgnpc.scp.purchase.service.INonContractProcessService;
import com.cgnpc.scp.purchase.service.IPurchaseContractItemService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/******************************
 * 用途说明: 调试采购-年度需求（非合同范围内）审批流程
 * 作者姓名: chenshijie
 * 创建时间: 2020/09/12 23:58
 ******************************/
@Service
public class NonContractProcessServiceImpl implements INonContractProcessService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ContractProcessServiceImpl.class);

    private static final String ACTIVITY_NAME_010 = "010_需求人提交年度采购需求";

    private static final String ACTIVITY_NAME_020 = "020_队办经理审批";

    private static final String ACTIVITY_NAME_030 = "030_计划协调员审批";

    private static final String ACTIVITY_NAME_040 = "040_调试采购主管审批";

    private static final String PROC_NAME = "pur_demOut";

    @Autowired
    IBpmCenterService bpmCenterService;

    @Autowired
    ICudFileService cudFileService;

    @Autowired
    NonContractProcessApplyMapper nonContractProcessApplyMapper;

    @Autowired
    ContractProcessItemMapper contractProcessItemMapper;

//    @Autowired
//    PurchaseContractItemMapper purchaseContractItemMapper;

    @Autowired
    NonContractProcessAuditMapper nonContractProcessAuditMapper;

    @Autowired
    ICommonProcessService commonProcessService;

    @Autowired
    CurrentUser currentUser;

    @Autowired
    private IPurchaseContractItemService purchaseContractItemService;

    /**********************************
     * 用途说明: 新建年度需求（非合同范围内）审批流程
     * 参数说明 params
     * 返回值说明:
     ***********************************/
    @Override
    @Transactional
    public ApiResult insertContract(String params) throws Exception {
        Map map = JSONObject.parseObject(params);

        map.put("folio","年度采购需求（非合同范围内）审批流程-" +
                new SimpleDateFormat("yyyyMMdd").format(new Date()));

        Map contractMap = (Map) map.get("win");

        NonContractProcessApply nonContractProcessApply = (NonContractProcessApply) BpmUtil.mapToObjectByJson(contractMap, NonContractProcessApply.class);

        nonContractProcessApply.setProcInstId("0");

        //判断是否为保存草稿
        if (!StringUtils.isEmpty(map.get("isSaveDraft"))) {
            //先处理业务
            modifyApplyInfo(nonContractProcessApply);
            //设置流程实例相关的列表ID  可用  针对流程的formInstID
            map.put("appFormId", nonContractProcessApply.getId());
            //保存草稿
            //保存草稿  假如从草稿修改过来，isModifyDraft为Y
            if (StringUtils.isEmpty(map.get("isModifyDraft"))) {
                return bpmCenterService.addDraft(map);
            }

            return ApiResult.success() ;
        } else {
            //先处理业务
            modifyApplyInfo(nonContractProcessApply);
            //设置流程实例相关的列表ID  可用  针对流程的formInstID
            map.put("appFormId", nonContractProcessApply.getId());
            //启动流程
            return bpmCenterService.startProcess(map);
        }
    }

    @Override
    public Object getActivityBusinessInfo(ActivityInfoParams activityInfoParams) throws Exception {
        if (ACTIVITY_NAME_010.equals(activityInfoParams.getActivityName())) {
            return getApplyById(activityInfoParams);
        } else if (ACTIVITY_NAME_020.equals(activityInfoParams.getActivityName()) ||
                ACTIVITY_NAME_030.equals(activityInfoParams.getActivityName()) ||
                ACTIVITY_NAME_040.equals(activityInfoParams.getActivityName())) {
            return getProcessAudit(activityInfoParams);
        } else {
            throw new ScpException("activity not found.");
        }
    }

    @Override
    public NonContractProcessApply getApplyById(ActivityInfoParams activityInfoParams) throws Exception {
        NonContractProcessApply nonContractProcessApply = null;
        if (!StringUtil.isNullOrSpace(activityInfoParams.getId())) {
            nonContractProcessApply = nonContractProcessApplyMapper.selectById(activityInfoParams.getId());
        } else if (!StringUtil.isNullOrSpace(activityInfoParams.getProcInstId())) {
//            NonContractProcessApplyExample nonContractProcessApplyExample = new NonContractProcessApplyExample();
//            nonContractProcessApplyExample.createCriteria().andProcInstIdEqualTo(activityInfoParams.getProcInstId());

            QueryWrapper<NonContractProcessApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("proc_inst_id", activityInfoParams.getProcInstId());
            List<NonContractProcessApply> nonContractProcessApplies = nonContractProcessApplyMapper.selectList(queryWrapper);
            if (nonContractProcessApplies.size() > 0) {
                nonContractProcessApply = nonContractProcessApplies.get(0);
            }
        } else {
            throw new ScpException("params error");
        }

        if (nonContractProcessApply == null) {
            throw new ScpException("details is missing");
        }

//        ContractProcessItemExample contractProcessItemExample = new ContractProcessItemExample();
//        contractProcessItemExample.createCriteria().andApplyIdEqualTo(nonContractProcessApply.getId());
//        List<ContractProcessItem> nonContractProcessItems = contractProcessItemMapper.selectByExample(contractProcessItemExample);

        QueryWrapper<ContractProcessItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_id", nonContractProcessApply.getId());
        List<ContractProcessItem> nonContractProcessItems = contractProcessItemMapper.selectList(queryWrapper);

        if (nonContractProcessItems != null && nonContractProcessItems.size() > 0) {
            List<String> itemIds = new ArrayList<>();
            for (ContractProcessItem nonContractProcessItem : nonContractProcessItems) {
                itemIds.add(nonContractProcessItem.getItemId());
            }
//            PurchaseContractItemExample purchaseContractItemExample = new PurchaseContractItemExample();
//            purchaseContractItemExample.createCriteria().andIdIn(itemIds);
//            List<PurchaseContractItem> purchaseContractItems = purchaseContractItemMapper.selectByExample(purchaseContractItemExample);

            List<PurchaseContractItem> purchaseContractItems = purchaseContractItemService.loadByIdList(itemIds);

            nonContractProcessApply.setPurchaseContractItemList(purchaseContractItems);
        }

        return nonContractProcessApply;
    }

    @Override
    public NonContractProcessAudit getProcessAudit(ActivityInfoParams activityInfoParams) throws Exception {
        if (StringUtil.isNullOrSpace(activityInfoParams.getProcInstId())) {
            throw new ScpException("procInstId is missing.");
        }
//        NonContractProcessAuditExample nonContractProcessAuditExample = new NonContractProcessAuditExample();
//        nonContractProcessAuditExample.createCriteria().
//                andProcInstIdEqualTo(activityInfoParams.getProcInstId()).
//                andActNameEqualTo(activityInfoParams.getActivityName());

        QueryWrapper<NonContractProcessAudit> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("proc_inst_id", activityInfoParams.getProcInstId()).eq("act_name",activityInfoParams.getActivityName());

        List<NonContractProcessAudit> nonContractProcessAudits = nonContractProcessAuditMapper.selectList(queryWrapper);
        if (nonContractProcessAudits.size() > 0) {
            return nonContractProcessAudits.get(0);
        }
        return null;
    }

    @Override
    public ApiResult deleteApplyAndMyDraft(Map paramsMap) throws Exception {
        String formId = paramsMap.get("id").toString();
        if (StringUtil.isNullOrSpace(formId)) {
            throw new ScpException("params error");
        }

        nonContractProcessApplyMapper.deleteById(formId);

//        ContractProcessItemExample contractProcessItemExample = new ContractProcessItemExample();
//        contractProcessItemExample.createCriteria().andApplyIdEqualTo(formId).andProcTypeEqualTo(2);
//        contractProcessItemMapper.deleteByExample(contractProcessItemExample);

        QueryWrapper<ContractProcessItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_id", formId).eq("proc_type",2);
        contractProcessItemMapper.delete(queryWrapper);

        ApiResult apiResult = bpmCenterService.deleteMyDraft(paramsMap);

        return apiResult;
    }

    @Override
    @Transactional
    public ApiResult submitProcess(String params) throws Exception {
        Map map = JSONObject.parseObject(params);
        // 流程除了启动环节，任意环节提交时均要保存流程实例id
        String procInstId = map.get("procInstId").toString();
        if (StringUtil.isNullOrSpace(procInstId)) {
            throw new ScpException("procInstId is missing.");
        }

        // 根据环节名称判断当前处理逻辑
        String act_name = map.get("act_name").toString();
        if (ACTIVITY_NAME_020.equals(act_name) ||
                ACTIVITY_NAME_030.equals(act_name) ||
                ACTIVITY_NAME_040.equals(act_name)) {
            processAudit(map);
        } else {
            throw new ScpException("activity not found.");
        }

        //判断是前进还是后退
        String flag = map.get("deal_answer").toString();
        ApiResult apiResult = null;
        if ("1".equals(flag)) {
            if(ACTIVITY_NAME_040.equals(act_name)) {
                // 归档环节插入流程公共表
                String appFormId = map.get("formInstID").toString();
                NonContractProcessApply nonContractProcessApply = nonContractProcessApplyMapper.selectById(appFormId);
                CommonProcess commonProcess = new CommonProcess();
                commonProcess.setApplyId(appFormId);
                commonProcess.setContactUser(nonContractProcessApply.getContactUser());
                commonProcess.setFolio(nonContractProcessApply.getFolio());
                commonProcess.setMobile(nonContractProcessApply.getMobile());
                commonProcess.setProcInstId(procInstId);
                commonProcess.setYear(nonContractProcessApply.getYear());
                commonProcess.setProcName(PROC_NAME);

                //生成需求号
                commonProcessService.updateDemandCode(appFormId);

                commonProcessService.insertCommonInfo(commonProcess);
            }
            apiResult = bpmCenterService.submitworklistitem(map);
        } else if ("2".equals(flag)) {
            apiResult = bpmCenterService.rollBackAction(map);
        }
        return apiResult;
    }

    @Override
    public void processAudit(Map map) throws Exception {
        // 流程除了启动环节，任意环节提交时均要保存流程实例id
        String procInstId = map.get("procInstId").toString();
        String deal_answer = map.get("deal_answer").toString();
        String auditNote = map.get("auditNote").toString();
        String act_name = map.get("act_name").toString();

        //根据procInstId查询业务表是否有数据
//        NonContractProcessAuditExample nonContractProcessAuditExample = new NonContractProcessAuditExample();
//        nonContractProcessAuditExample.createCriteria().
//                andProcInstIdEqualTo(procInstId).
//                andActNameEqualTo(act_name);

        QueryWrapper<NonContractProcessAudit> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("proc_inst_id", procInstId).eq("act_name",act_name);

        List<NonContractProcessAudit> nonContractProcessAudits = nonContractProcessAuditMapper.selectList(queryWrapper);
        if (nonContractProcessAudits.size() > 0) {
            //业务数据存在执行更新操作
            NonContractProcessAudit nonContractProcessAudit = nonContractProcessAudits.get(0);
            UserInfo userinfo = currentUser.getCurrentUserDetail();
            nonContractProcessAudit.setLastUpdateUser(userinfo.getUserId());
            nonContractProcessAudit.setLastUpdateUserName(userinfo.getUserName());
            nonContractProcessAudit.setLastUpdateTime(new Date());
            nonContractProcessAudit.setProcInstId(procInstId);
            nonContractProcessAudit.setDealAnswer(Integer.parseInt(deal_answer));
            nonContractProcessAudit.setAuditNote(auditNote);
            nonContractProcessAuditMapper.updateById(nonContractProcessAudit);

        } else {
            //业务数据不存在执行插入操作
            NonContractProcessAudit nonContractProcessAudit = new NonContractProcessAudit();
            UserInfo userinfo = currentUser.getCurrentUserDetail();
            nonContractProcessAudit.setCreateUser(userinfo.getUserId());
            nonContractProcessAudit.setCreateUserName(userinfo.getUserName());
            nonContractProcessAudit.setCreateTime(new Date());
            nonContractProcessAudit.setProcInstId(procInstId);
            nonContractProcessAudit.setActName(act_name);
            nonContractProcessAudit.setId(IDHelper.uuid());
            nonContractProcessAudit.setDealAnswer(Integer.parseInt(deal_answer));
            nonContractProcessAudit.setAuditNote(auditNote);
            nonContractProcessAuditMapper.insert(nonContractProcessAudit);
        }
    }

    private void modifyApplyInfo(NonContractProcessApply nonContractProcessApply) {
        // 根据id判断之前是否已经保存过数据,有则更新，无则插入
        if (StringUtil.isNullOrSpace(nonContractProcessApply.getId())) {
            nonContractProcessApply.setId(IDHelper.uuid());
            nonContractProcessApply.setCreateTime(new Date());
            UserInfo userinfo = currentUser.getCurrentUserDetail();
            nonContractProcessApply.setCreateUser(userinfo.getUserId());
            nonContractProcessApply.setCreateUserName(userinfo.getUserName());
            nonContractProcessApplyMapper.insert(nonContractProcessApply);
            insertItem(nonContractProcessApply);
        } else {
            UserInfo userinfo = currentUser.getCurrentUserDetail();
            nonContractProcessApply.setLastUpdateUser(userinfo.getUserId());
            nonContractProcessApply.setLastUpdateUserName(userinfo.getUserName());
            nonContractProcessApply.setLastUpdateTime(new Date());
            nonContractProcessApplyMapper.updateById(nonContractProcessApply);

//            ContractProcessItemExample contractProcessItemExample = new ContractProcessItemExample();
//            contractProcessItemExample.createCriteria().andApplyIdEqualTo(nonContractProcessApply.getId()).andProcTypeEqualTo(2);
//            contractProcessItemMapper.deleteByExample(contractProcessItemExample);

            QueryWrapper<ContractProcessItem> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("apply_id", nonContractProcessApply.getId()).eq("proc_type",2);
            contractProcessItemMapper.delete(queryWrapper);

            insertItem(nonContractProcessApply);
        }

    }

    private void insertItem(NonContractProcessApply nonContractProcessApply) {
        UserInfo userinfo = currentUser.getCurrentUserDetail();

        for (PurchaseContractItem item : nonContractProcessApply.getPurchaseContractItemList()) {
            ContractProcessItem contractProcessItem = new ContractProcessItem();
            contractProcessItem.setItemId(item.getId());
            contractProcessItem.setProcType(2);
            contractProcessItem.setId(IDHelper.uuid());
            contractProcessItem.setApplyId(nonContractProcessApply.getId());
            contractProcessItem.setCreateUser(userinfo.getUserId());
            contractProcessItem.setCreateUserName(userinfo.getUserName());
            contractProcessItem.setCreateTime(new Date());
            contractProcessItemMapper.insert(contractProcessItem);
        }
    }

}
